0%

用Embedding表达一切

Embedding 的概念来自于 word embeddings。 Embedding is a transformation from discrete values/scalars to dense real value vectors. 有的地方把 embedding 翻译为嵌套,有的地方把它翻译为向量。

Embedding 是一个行为,把离线形式的事物影响为实数向量。Embedding 这个词同时也是该行为所输出的东西,我们把输出的实数向量也称作是 Embedding。

An embedding is a mapping from discrete objects, such as words, to vectors of real numbers.

An embedding is a relatively low-dimensional space into which you can translate high-dimensional vectors. Embeddings make it easier to do machine learning on large inputs like sparse vectors representing words. Ideally, an embedding captures some of the semantics of the input by placing semantically similar inputs close together in the embedding space. An embedding can be learned and reused across models.

它可以单独使用来学习一个单词嵌入,以后可以保存并在另一个模型中使用,比如作为特征。 它可以用作深度学习模型的一部分,其中嵌入与模型本身一起学习。 它可以用来加载预先训练的词嵌入模型,这是一种迁移学习。 它可以用来做相似召回,在某种空间计算 embedding 的相似度。

广告、推荐、搜索等领域用户数据的稀疏性几乎必然要求在构建 DNN 之前对 user 和 item 进行 embedding 后才能进行有效的训练。

深度学习中设计离散特征的话一般都处理成 Embedding 的形式,作为网络的底部(第一层),一般对整体网络效果有着重要的作用。

在 Keras 中有专门的 Embedding 层,其作用是:Turns positive integers (indexes) into dense vectors of fixed size. eg. [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]] This layer can only be used as the first layer in a model.

1
2
3
4
5
6
7
8
keras.layers.Embedding(input_dim,
output_dim,
embeddings_initializer='uniform',
embeddings_regularizer=None,
activity_regularizer=None,
embeddings_constraint=None,
mask_zero=False,
input_length=None)

对应的 TFlearn 中的 Embedding 层:

1
2
3
4
5
6
7
8
9
10
tflearn.layers.embedding_ops.embedding(incoming,
input_dim,
output_dim,
validate_indices=False,
weights_init='truncated_normal',
trainable=True,
restore=True,
reuse=False,
scope=None,
name='Embedding')

在 Tensorflow 中也可以在网络结构中加入 Embedding 层:

1
2
3
embeddings = tf.Variable(tf.random_uniform([voc_size, embedding_size], -1.0, 1.0))
...
embed = tf.nn.embedding_lookup(embeddings, train_inputs) # lookup table

嵌入层被定义为网络的第一个隐藏层。它必须指定 3 个参数:

1
2
3
- input_dim:这是文本数据中词汇的取值可能数。例如,如果您的数据是整数编码为0-9之间的值,那么词汇的大小就是10个单词;
- output_dim:这是嵌入单词的向量空间的大小。它为每个单词定义了这个层的输出向量的大小。例如,它可能是32或100甚至更大,可以视为具体问题的超参数;
- input_length:这是输入序列的长度,就像您为Keras模型的任何输入层所定义的一样,也就是一次输入带有的词汇个数。例如,如果您的所有输入文档都由1000个字组成,那么input_length就是1000。

被 Embedding 的对象(比如 word)必须是有限个数的。embedding 层要求输入数据是整数编码的,所以每个 word 都用一个唯一的整数表示。这个数据准备步骤可以使用 Keras 提供的 Tokenizer API 来执行。

嵌入层的输出是一个二维向量,每个 word 在输入文本(输入文档)序列中嵌入一个。

在 word2vec 中,学习的目标是一个 word 的 Embedding 表达,文本语料是学习的来源,我们通过一个 word 的 context 来学习这个 word 的表达,context 指的是一段语料中某 word 相邻的 words。 在广告推荐等领域中,如果要做 item Embedding,那么 context 可以是一个用户点击行为中某被点击 item 相邻的被点击 items。

怎么把 raw format 的 feature data 转变为 embedding format(也就是浮点数向量 vector) 的 embedding data?

下面链接讲了我们如何用 TensorFlow 做 embedding https://www.tensorflow.org/guide/embedding
下面两个链接讲的典型的 word embedding,即 word2vec。 https://github.com/tensorflow/models/tree/master/tutorials/embedding
https://www.tensorflow.org/tutorials/representation/word2vec

嵌入层用随机权重进行初始化,并将学习训练数据集中所有单词的嵌入。

首先要有语料库,把它切分为 word,每个 word 赋予一个 int 作为 id。 比如语料 “I have a cat.”, [“I”, “have”, “a”, “cat”, “.”] vocabulary_size = 5 embedding_size = len(embedding-vector) word_ids = [1,2,3,4,5] embedded_word_ids = [[1, xxx], [2, yyy]…,[5, zzz]]

1
2
word_embeddings = tf.get_variable(“word_embeddings”, [vocabulary_size, embedding_size])
embedded_word_ids = tf.nn.embedding_lookup(word_embeddings, word_ids)

embeddings is a matrix where each row represents a word vector.

embedding_lookup is a quick way to get vectors corresponding to train_inputs.

tf.nn.embedding_lookup 这个函数到底做了什么?https://stackoverflow.com/questions/34870614/what-does-tf-nn-embedding-lookup-function-do embedding_lookup 不是简单的查表,id 对应的向量是可以训练的,训练参数个数应该是 category num * embedding size,也就是说 lookup 是一种全连接层。

下面是 word2vec 实现的最简单的版本,这里只展示网络结构的部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
train_inputs = tf.placeholder(tf.int32, shape=[batch_size])

train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1])


with tf.device('/cpu:0'):

embeddings = tf.Variable(tf.random_uniform([voc_size, embedding_size], -1.0, 1.0))
embed = tf.nn.embedding_lookup(embeddings, train_inputs)


nce_weights = tf.Variable(tf.random_uniform([voc_size, embedding_size], -1.0, 1.0))
nce_biases = tf.Variable(tf.zeros([voc_size]))





loss = tf.reduce_mean(tf.nn.nce_loss(nce_weights, nce_biases, train_labels, embed, num_sampled, voc_size))

train_op = tf.train.AdamOptimizer(1e-1).minimize(loss)

方法一:对稀疏的 id 做聚类处理

把一个 embedding 在 tensorboard 上可视化出来,需要做三件事。

  1. Setup a 2D tensor that holds your embedding(s).

  2. Periodically save your model variables in a checkpoint in LOG_DIR.

  3. (Optional) Associate metadata with your embedding.

参考 https://stackoverflow.com/questions/40849116/how-to-use-tensorboard-embedding-projector

word2vec(query2vec)

item2vec(doc2vec)

user2vec

query 中每一个词蕴含的信息可以通过训练数据中由其召回的 item 所表达。

query 的 Embedding 是由其切词后各个分词的 Embedding 所结合而成的。

item 和 user 的量可以认为是无限的,所以不能直接使用它们的 index 来构建。我们可以用其某些有限的属性来表达它们。比如,说 user,其实聊的是 user 喜欢什么 item,接触过什么 item,那么其中的核心其实还是 item,这样理解的话,user 的 Embedding 其实就源自于若干个与之相关的 item 的 Embedding。

这里的核心就在于,如何结合用户有过行为的若干个 item 的 Embedding,合成一个 User Embedding。

将 word embedding 和 item embedding 放到同一个网络里训练。也就意味着使用同一个语料进行训练。

Embedding 是一种方法,而它不是直接去解决目标问题的模型,但有了它作为模型或者输入的一部分,需要问题能够方便的求解。

Word-embedding 是基础: https://paperswithcode.com/task/word-embeddings

Item-embedding:

Query-embedding:

User-embedding:

Alibaba - Learning and Transferring IDs Representation in E-commerce

解读:https://zhuanlan.zhihu.com/p/56119617

user embedding 就是网络的最后一个隐层,video embedding 是 softmax 的权重.

将最后 softmax 层的输出矩阵的列向量当作 item embedding vector,而将 softmax 之前一层的值当作 user embedding vector。

主要做法是把 item 视为 word,用户的行为序列视为一个集合,item 间的共现为正样本,并按照 item 的频率分布进行负样本采样,缺点是相似度的计算还只是利用到了 item 共现信息,1). 忽略了 user 行为序列信息; 2). 没有建模用户对不同 item 的喜欢程度高低。

Item2vec 中把用户浏览的商品集合等价于 word2vec 中的 word 的序列.

https://github.com/facebookresearch/starspace

这个命令行工具用起来很简单:input.txt 中每一行是一个 session 中的 item 序列。

./starspace train -trainFile input.txt -model pagespace -label ‘page’ -trainMode 1

https://github.com/zalandoresearch/flair A text embedding library

https://github.com/facebookresearch/PyTorch-BigGraph

https://gist.github.com/nzw0301/333afc00bd508501268fa7bf40cafe4e